
#include <glib.h>
#include <stdio.h>

#include <unistd.h>
#include <sys/timeb.h>
#include <semaphore.h>
#include <sys/types.h>

#include "lora_task.h"
#include "encrypt/chachapoly.h"
#include "LoRA.h"

#include "pack.h"
#include "ota.h"
#include "log.h"

gpointer lora_task(gpointer data);

static GThread*     lora_task_h = NULL;

static uint8_t      ReceiveBuffer[MAX_LORA_BUFFER_SIZE];
static uint8_t      SendBuffer[MAX_LORA_BUFFER_SIZE];

int8_t	rssi, snr;

void lora_task_init() {
    lora_task_h = g_thread_new("LoRA thread", lora_task, NULL);
}

void lora_task_uninit() {
    g_thread_unref(lora_task_h);
}


static sem_t   LoRA_irq_sem;
// static struct timespec wait_time = {
//     .tv_sec = 0,
//     .tv_nsec = 100 * 1000 * 1000,
// };

static struct timespec wait_time = {
    .tv_sec = 5,
    .tv_nsec = 0,
};

void LoRA_IRQ()
{
    // 设置事件，让主线程获得事件，然后读取接收到的数据
    sem_post(&LoRA_irq_sem);
}

gpointer lora_task(gpointer data) {
    bool            ret;
    uint8_t         size;
    int             r;
    uint16_t        irq_type;
    uint8_t         packSize;
    uint8_t         no;

    log_print(LOG_INFO, "LoRA thread......");

    // 初始化sem
    r = sem_init(&LoRA_irq_sem, 0, 0);

    payload_aead_init();

    ret = LoRA_Open(LoRA_IRQ);

    log_print(LOG_INFO, "LoRA open %d.", ret);

    while (1)
    {
        LoRA_StartReceive();

        while (1)
        {
            r = sem_wait(&LoRA_irq_sem);

            if (r != 0)
            {
                continue;
            }

            // log_print(LOG_DEBUG, "LoRA irq");
            irq_type = LoRA_GetIRQ();

            if ( IRQ_RX_DONE & irq_type )
            {
                size = sizeof(ReceiveBuffer);
                ret = LoRA_Read(ReceiveBuffer, &size);

                log_print(LOG_DEBUG, "LoRA receive %d bytes", size);

                // 解码
				// int8_t		rssi, snr;

				LoRA_GetPacketStatus(&rssi, &snr);
                log_print(LOG_DEBUG, "RSSI=%d, SNR=%d", rssi, snr);
                
                packSize = unpackData(ReceiveBuffer, size, &no, SendBuffer);

                // 回应
                if (packSize != 0) {
                    log_print(LOG_DEBUG, "Decode %d bytes", packSize);
                    
                    LoRA_Write(SendBuffer, packSize);

                    while (1)
                    {
                        r = sem_wait(&LoRA_irq_sem);
                        if (r != 0)
                        {
                            continue;
                        }

                        irq_type = LoRA_GetIRQ();
                        if (IRQ_TX_DONE & irq_type) {
                            break;
                        }
                    }
                    // usleep(300 * 1000);
                }

                break;
            }
            else
            {
                break;
            }         
        }
    }

    LoRA_Close();

    sem_destroy(&LoRA_irq_sem);

    return 0;
}

